/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.scene.controller;

import com.koron.common.Excel;
import com.koron.common.StaffAttribute;
import com.koron.common.bean.StaffBean;
import com.koron.common.domain.DataBean;
import com.koron.common.permission.SPIAccountAnno;
import com.koron.common.web.Util;
import com.koron.hiddendanger.domain.HiddenDangerDiscovery;
import com.koron.scene.bean.CalibrationHistoryView;
import com.koron.scene.bean.CheckResultView;
import com.koron.scene.domain.Device;
import com.koron.scene.service.api.DeviceService;
import com.koron.scene.utils.BusinessCode;
import com.koron.system.annotation.Log;
import com.koron.system.discrete.BusinessManipulation;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.swan.bean.MessageBean;
import springfox.documentation.annotations.ApiIgnore;

import java.io.File;
import java.io.InputStream;
import java.sql.Timestamp;
import java.util.*;

@Api(tags = "device", description = "设备台账接口")
@RestController
@RequestMapping("/device")
public class DeviceController {

    private final static  Logger logger = LoggerFactory.getLogger(DeviceController.class);

    @Autowired
    private DeviceService deviceService;
    @Autowired
    private Util util;

    private void setProperties(Device source, StaffBean user) {
        source.setAddUser(user.getCode());
        source.setAddUserName(user.getName());
        source.setAddTime(new Date());
        source.setUpdateUserName(user.getName());
        source.setUpdateUser(user.getCode());
        source.setUpdateTime(source.getAddTime());
        if (source.getStatus() == null) {
            source.setStatus(1);
        }
    }


    @ApiOperation("存储管理的设备")
    @RequestMapping(value = "/save.htm", method = {RequestMethod.POST})
    @Log(title = "新增、修改设备", businessModule = "设备台账", businessManipulation = BusinessManipulation.INSERT)
    public MessageBean<String> save(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, @RequestBody Device device) {
        if (user == null) {
            return MessageBean.create(BusinessCode.NO_LOGIN.getCode(), BusinessCode.NO_LOGIN.getDescription(), String.class);
        }
        if (device == null) {
            return MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), String.class);
        }
        if (StringUtils.isBlank(device.getGridName()) || StringUtils.isBlank(device.getDeviceName()) || StringUtils.isBlank(device.getCheckEmployeeName())) {
            return MessageBean.create(BusinessCode.INSUFFICIENT_PARAM.getCode(), BusinessCode.INSUFFICIENT_PARAM.getDescription(), String.class);
        }
        setProperties(device, user);
        Integer result = deviceService.persist(device);
        BusinessCode bc = BusinessCode.valueOf(result);
        MessageBean<String> msg = MessageBean.create(bc.getCode(), bc.getDescription(), String.class);
        if (result.intValue() == BusinessCode.SUCCESS.getCode()) {
            msg.setData(device.getId());
        }
        return msg;
    }


    @ApiOperation("批量删除设备")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "设备Id,多个之间用逗号分开", required = true, dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/batchDelete.htm", method = RequestMethod.POST)
    @Log(title = "批量删除设备", businessModule = "设备台账", businessManipulation = BusinessManipulation.DELETE)
    public MessageBean<Boolean> batchDelete(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, String ids) {
        MessageBean<Boolean> msg = new MessageBean<>();
        if (user == null) {
            msg.setCode(BusinessCode.NO_LOGIN.getCode());
            msg.setDescription(BusinessCode.NO_LOGIN.getDescription());
            return msg;
        }
        if (StringUtils.isEmpty(ids)) {
            return MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), Boolean.class);
        }
        try {
            String[] idArray = ids.split("[,，]");
            msg.setData(deviceService.batchDetele(Arrays.asList(idArray)));
            msg.setDescription(BusinessCode.SUCCESS.getDescription());
            msg.setCode(BusinessCode.SUCCESS.getCode());
            return msg;
        } catch (Exception e) {
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }
    }


    @ApiOperation("查询设备列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "corpCode", value = "公司code" , paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "gridCode", value = "网格编码" , dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "deviceName", value = "设备名称" , dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "deviceTypeId", value = "设备类型Id" , dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "deptName", value = "所属部门名称" , dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "checkEmployeeName", value = "检查负责人姓名" , dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "calibrationExpiredDate", value = "校验到期日期" , dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "状态, 0停用、1正常" , dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "keyword", value = "关键字" , dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "当前页", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/list.htm", method = RequestMethod.POST)
    public MessageBean<DataBean<Device>> list(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, @RequestParam(required = false) String corpCode, @RequestParam(required = false) String gridCode, @RequestParam(required = false) String deviceName, @RequestParam(required = false) String deviceTypeId,
                                              @RequestParam(required = false) String deptName, @RequestParam(required = false) String checkEmployeeName, @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date calibrationExpiredDate,@RequestParam(required = false) String keyword,
                                              @RequestParam(required = false) Integer status, @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "15") Integer pageSize ) {
        MessageBean<DataBean<Device>> msg = new MessageBean<>();
        if (user == null) {
            msg.setCode(BusinessCode.NO_LOGIN.getCode());
            msg.setDescription(BusinessCode.NO_LOGIN.getDescription());
            return msg;
        }
        Integer start = (page <= 1) ? 0 : (page - 1) * pageSize;
        try {
            Timestamp stamp = null;
            if (calibrationExpiredDate != null) {
                stamp = new Timestamp(calibrationExpiredDate.getTime());
            }
            DataBean<Device> dataBean = deviceService.fetchDevices(corpCode, gridCode, deviceName, deviceTypeId, deptName, checkEmployeeName, stamp, status, start, pageSize,keyword);
            msg.setData(dataBean);
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription(BusinessCode.SUCCESS.getDescription());
        } catch (Exception e) {
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }


    @ApiOperation("设备详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "设备Id", required = true, dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/detail.htm", method = RequestMethod.POST)
    public MessageBean<Device> detail(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, @RequestParam(required = true) final String id) {
        MessageBean<Device> msg = new MessageBean<>();
        if (user == null) {
            msg.setCode(BusinessCode.NO_LOGIN.getCode());
            msg.setDescription(BusinessCode.NO_LOGIN.getDescription());
            return msg;
        }
        try {
            if (StringUtils.isEmpty(id)) {
                msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
                msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
                return msg;
            }
            msg.setData(deviceService.fetchOne(id));
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription(BusinessCode.SUCCESS.getDescription());
        } catch (Exception e) {
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }


    @ApiOperation("导出设备列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "corpCode", value = "公司code" , paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "gridCode", value = "网格编码" , dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "deviceName", value = "设备名称" , dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "deviceTypeId", value = "设备类型" , dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "deptName", value = "所属部门名称" , dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "checkEmployeeName", value = "检查负责人姓名" , dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "calibrationExpiredDate", value = "校验到期日期" , dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "状态, 0停用、1正常" , dataType = "int", paramType = "query")
    })
    @RequestMapping(value = "/export.htm", method = RequestMethod.GET)
    public HttpEntity<?> export(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, @RequestParam(required = false) String corpCode, @RequestParam(required = false) String gridCode, @RequestParam(required = false) String deviceName, @RequestParam(required = false) String deviceTypeId,
                                @RequestParam(required = false) String deptName, @RequestParam(required = false) String checkEmployeeName, @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date calibrationExpiredDate,
                                @RequestParam(required = false) Integer status) {
        if (null == user) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        File file = new File("static/excel/deviceList.xlsx");
        try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("static/excel/deviceList.xlsx")) {
            Timestamp stamp = null;
            if (calibrationExpiredDate != null) {
                stamp = new Timestamp(calibrationExpiredDate.getTime());
            }
            DataBean<Device> dataBean = deviceService.fetchDevices(corpCode, gridCode, deviceName, deviceTypeId, deptName, checkEmployeeName, stamp, status, null, null,null);
            map.put("data", dataBean.getList());
            FileUtils.copyInputStreamToFile(inputStream, file);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
        }
        return Excel.createFile("设备台账", file, "deviceList.btl", map);
    }

    @ApiOperation("下载模板")
    @RequestMapping(value = "/exportTemplate.htm", method = {RequestMethod.GET})
    public HttpEntity<?> exportExcelTemplate(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user) {
        if (null == user) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        File targetFile = new File("static/excel/deviceTemplate.xlsx");
        try {
            InputStream initialStream = getClass().getClassLoader().getResourceAsStream("static/excel/deviceTemplate.xlsx");
            FileUtils.copyInputStreamToFile(initialStream, targetFile);
        } catch (Exception e) {

            logger.error(e.getMessage(),e);
        }
        return Excel.createFile("设备台账模板", targetFile, "default.btl", map);
    }

    @ApiOperation("导入设备台账列表")
    @ApiImplicitParams({@ApiImplicitParam(name = "file", value = "上传的excel文件", required = true, paramType = "query", dataType = "file")
    })
    @RequestMapping(value = "/importExcel.htm", method = RequestMethod.POST)
    public MessageBean<?> importExcel(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, @RequestParam(required = false) String userCode,
                                      @RequestParam(required = true) final MultipartFile file) {

        if (null == user) {//用于解决postman测试文件上传试的登陆问题
            List<StaffBean> staffBeanList = (List<StaffBean>) util.staff(userCode, null).getData();
            if (null != staffBeanList && staffBeanList.size() > 0) {
                user = staffBeanList.get(0);
            }
        }
        MessageBean<Integer> msg = new MessageBean<>();
        if (null == user) {
            msg.setCode(BusinessCode.NO_LOGIN.getCode());
            msg.setDescription(BusinessCode.NO_LOGIN.getDescription());
            return msg;
        }
        if (null == file) {
            msg.setCode(BusinessCode.FILE_IS_EMPTY.getCode());
            msg.setDescription(BusinessCode.FILE_IS_EMPTY.getDescription());
            return msg;
        }
        return deviceService.importExcel(user, file);
    }


    @ApiOperation("设备的检查历史记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deviceId", value = "设备Id", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "deviceName", value = "设备名称", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "当前页", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/resultHistory.htm", method = RequestMethod.POST)
    public MessageBean<DataBean<CheckResultView>> resultHistory(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, @RequestParam String deviceId, @RequestParam String deviceName,
                                                                @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "15") Integer pageSize) {
        MessageBean<DataBean<CheckResultView>> msg = new MessageBean<>();
        if (user == null) {
            msg.setCode(BusinessCode.NO_LOGIN.getCode());
            msg.setDescription(BusinessCode.NO_LOGIN.getDescription());
            return msg;
        }
        Integer start = (page <= 1) ? 0 : (page - 1) * pageSize;
        try {
            if (StringUtils.isBlank(deviceId)) {
                msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
                msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
                return msg;
            }
            msg.setData(deviceService.checkHistory(deviceName, deviceId, start, pageSize));
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription(BusinessCode.SUCCESS.getDescription());
        } catch (Exception e) {
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }


    @ApiOperation("设备的检验历史记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deviceId", value = "设备Id", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "deviceName", value = "设备名称", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "当前页", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/calibrationHistory.htm", method = RequestMethod.POST)
    public MessageBean<DataBean<CalibrationHistoryView>> calibrationHistory(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, @RequestParam String deviceId, @RequestParam String deviceName,
                                                                            @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "15") Integer pageSize) {
        MessageBean<DataBean<CalibrationHistoryView>> msg = new MessageBean<>();
        if (user == null) {
            msg.setCode(BusinessCode.NO_LOGIN.getCode());
            msg.setDescription(BusinessCode.NO_LOGIN.getDescription());
            return msg;
        }
        Integer start = (page <= 1) ? 0 : (page - 1) * pageSize;
        try {
            if (StringUtils.isBlank(deviceId)) {
                msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
                msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
                return msg;
            }
            DataBean<CalibrationHistoryView> dataBean = deviceService.calibrationHistory(deviceName, deviceId, start, pageSize);
            msg.setData(dataBean);
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription(BusinessCode.SUCCESS.getDescription());
        } catch (Exception e) {
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }

    @ApiOperation("查询设备检查的隐患")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "hiddenDangerIds", value = "隐患id, 多个id以逗号分隔", required = true, dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/queryDangers.htm", method = RequestMethod.POST)
    public MessageBean<List<HiddenDangerDiscovery>> getHiddenDanger(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, @RequestParam String hiddenDangerIds) {
        MessageBean<List<HiddenDangerDiscovery>> msg = new MessageBean<>();
        if (user == null) {
            msg.setCode(BusinessCode.NO_LOGIN.getCode());
            msg.setDescription(BusinessCode.NO_LOGIN.getDescription());
            return msg;
        }
        try {
            if (StringUtils.isBlank(hiddenDangerIds)) {
                msg.setCode(BusinessCode.SUCCESS.getCode());
                msg.setDescription(BusinessCode.SUCCESS.getDescription());
                msg.setData(Collections.EMPTY_LIST);
                return msg;
            }
            msg.setData(deviceService.getHiddenDangers(Arrays.asList(hiddenDangerIds.split(","))));
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription(BusinessCode.SUCCESS.getDescription());
        } catch (Exception e) {
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }


}
